package cn.hicard.risk.action.bd;

import java.io.ByteArrayOutputStream;
import java.util.ArrayList;
import java.util.List;
import org.apache.log4j.Logger;
import cn.hicard.risk.common.Constant;
import cn.hicard.core.Where;
import cn.hicard.core.Page;
import cn.hicard.core.PageResult;
import cn.hicard.risk.entity.BdCallorder;
import cn.hicard.risk.entity.BdMerchinfo;
import cn.hicard.risk.report.ReportTemplet;
import cn.hicard.risk.service.bd.CallorderService;
import cn.hicard.risk.task.JzgSyncRunnable;
import cn.hicard.util.DateHelp;

/**
 * 紧急调单处理相关供FLEX调用的类
 * @author zhangy
 *
 */
public class CallorderFlex {
	
	/** 日志记录工具 */
	private static Logger logger = Logger.getLogger(Constant.LOGGER_MAIN);
	
	/** 调单业务类 */
	private CallorderService callorderService;

	public void setCallorderService(CallorderService service) {
		this.callorderService = service;
	}
	
	/** 未处理*/
	public static final String UNTREATED= "0";
	/** 审核通过*/
	public static final String PASS= "1";
	/** 审核未通过*/
	public static final String FAIL= "2";

	/**
	 * 按条件分页搜索<BR/>
	 * <P>由于在2013年03月25日14时11分，对整体构架进行了一次更新，这回特别做一下说明。
	 * 如果你是往后接管这个项目的朋友，请不要觉得这个方法与以往的比较不同。
	 * 如果我有时间的话，就会把所的这这类型方法都改了，你就看不到这段注释了。
	 * 你能看到就说明我没时间改了，或者我辞了，或者我忘了。
	 * </P>
	 * 　　cn.hicard.risk.action包下的类基本上都是为Flash的RemoteObject直接调用的，
	 * 所以这里的所有类的方法的参数不可以随意改动，改动之处必须和Flash关系起来。<BR/>
	 * 　　以往的做法是把参数放入单个对象，但是遇到特别点的条件就麻烦了，
	 * 比如日期区间条件、非（不等，等混合）等单一对象就无法表示了，
	 * 这里用新引入的“参数容器对象Condition<T>”解决，具体实现原理比较简单，可参考源代码注释说明。
	 * 由于前技术Flex的限制，Condition<T>是在Java与Flex交互的flex层生成（如果是使用JSP就比较便了）
	 * 传往层（一般来说是由Dao层）具体处理。
	 * 　　另外，再提一点，本项目还是由于FLEX技术限术制，无法使用Hibernate一些高级功能，
	 * 目前的构架是仅用Hibernate来写代替SQL，不过比起SQL来也是超方便的！赞一个！(我讨厌写SQL)
	 * @param start
	 * @param end
	 * @param page
	 * @return
	 * @throws Exception
	 */
	public PageResult<BdCallorder> search(BdCallorder start, BdCallorder end, BdMerchinfo merch, Page page) throws Exception{
		try {
			Where condition = new Where(BdCallorder.class);
			// 使用SQL查询，不检查字段是否存在
			condition.setMode(Where.MODE_NOT_CHECK);
			
			// 这里的Condition的add项就完全跟FLEX调用画面的条件对应起来吧
			
			// 订单号
			String orderno = start.getOrderno();
			condition.addEqual("c.orderno", orderno);	
			
			// 汇卡商户号
			String wpmerchno = start.getWpmerchno();
			condition.addEqual("c.wpmerchno", wpmerchno);
			
			// 银联商户号
			String merchno = start.getMerchno();
			condition.addEqual("c.merchno", merchno);
			
			// 终端号
			String termno = start.getTermno();
			condition.addEqual("c.termno", termno);
			
			// 商户名
			String merchName = start.getMerchname();
			condition.addLike("c.merchname", merchName);
			
			// 打印商户名
			//String printName = merch.getMerchacc();
			//condition.addLike("m.merchacc", printName);	
			
			// 业务类型
			String datatype = start.getDatatype();
			condition.addEqual("c.datatype", datatype);
			
			// 交易日期开始
			String transdateStart = start.getTransdate();
			condition.addGreaterEq("c.transdate", transdateStart);
			// 交易日期结束
			String transdateEnd = end.getTransdate();			
			condition.addLessEq("c.transdate", transdateEnd);
			
			//审核状态
			String checkstate = start.getCheckstate();			
			if( checkstate.startsWith("!")){
				condition.addNotEqual("c.checkstate", checkstate.substring(1));
			}else{
				condition.addEqual("c.checkstate", checkstate);
			}		
			
			// 是否上传图片，图片名字作条件，1代表已上传，0代表未上传，空值不加条件表示全部。
			String picname = start.getPicname();
			// 不要忽略空值
			condition.setMode(Where.MODE_NOT_IGNORE);
			if("1".equals(picname)){
				condition.addNotEqual("c.picname", "");
			}else if("0".equals(picname)){
				condition.addEqual("c.picname", "");
			}
			// 用完后立即还原为忽略空值，否则怕忘了以后再加搜索条件时无效
			condition.setMode(Where.MODE_IGNORE);
			
			// 是否发送短信
			String isSendSms = merch.getGetTicket();
			condition.addEqual("m.iswatch", isSendSms);
			
			return callorderService.search(condition, page);
		} catch (Exception e) {
			logger.error("", e);
			throw e;
		}
	}
	
	/**
	 * 更新多条记录
	 * @param list
	 * @throws Exception
	 */
	public void updateList(List<BdCallorder> list) throws Exception{
		
		// 用于存放筛选出的金掌柜的数据
		List<BdCallorder> jzgList = new ArrayList<BdCallorder>();
		
	  for (BdCallorder callorder : list) {
			callorder.setProcdate(DateHelp.dateTime());	
			
			//筛选出金掌柜的数据发送到汇卡网管理系统
			if("jzg".equals(callorder.getDatatype())){
				jzgList.add(callorder);
			}
		}
		
		// 更新数据库状态
		try {
			// 更新数据库
			callorderService.updateList(list);
			
			// 丢进线程的处理队列中
			JzgSyncRunnable.offerToQueue(jzgList);
			
		} catch (Exception e) {
			logger.error("", e);
			throw e;
		}
	}
	
	public void changeJzg(List<BdCallorder> list)throws Exception{
		// 用于存放筛选出的金掌柜的数据
		List<BdCallorder> jzgList = new ArrayList<BdCallorder>();
		for (BdCallorder callorder : list) {
			callorder.setProcdate(DateHelp.dateTime());	
			
			// 筛选出金掌柜的数据发送到汇卡网管理系统
			if("jzg".equals(callorder.getDatatype())){
				jzgList.add(callorder);
			}
		}
		try {
		  // 丢进线程的处理队列中
		  JzgSyncRunnable.offerToQueue(jzgList);
		  logger.info("筛选出金掌柜的"+jzgList.size()+"条数据已发送到汇卡网管理系统");
		} catch (Exception e) {
			logger.error("", e);
			throw e;
		}
	}

	/**
	 * 查询风控传统POS冻结报表
	 * @param start
	 * @param end
	 * @return
	 * @throws Exception 
	 */
	public List<BdCallorder> findFreezeReport(BdCallorder start, BdCallorder end) throws Exception{
		//1.只要是需要调单的数据  未处理和审核未通过 0、2
		start.setCheckstate(UNTREATED);
		end.setCheckstate(FAIL);
		//String checkState = "0,2";
		//2.限制交易日期
		try {
			return callorderService.findList(start, end);
		} catch (Exception e) {
			logger.error("查询风控传统POS冻结报表出错", e);
			throw e;
		}
	}
	
	/**
	 * 下载风控传统POS冻结报表
	 * @param start
	 * @param end
	 * @return
	 */
	public byte[] downloadFreezeReport(BdCallorder start, BdCallorder end){		
		// 查询出需要冻结的数据
		List<BdCallorder> freezeList = null;
		try {
			freezeList = findFreezeReport(start, end);
		} catch (Exception e) {
			logger.error("",e);
		}
		if(freezeList == null){
			freezeList = new  ArrayList<BdCallorder>();
		}
		
		// 构建报表
		ReportTemplet rt = new ReportTemplet();
		
		String title = "风控传统pos冻结报表";
		String descrip = "条件：共计 " 
							  + freezeList.size() 
							  + " 条，报表下载开始时间： " + start.getTransdate() 
							  + "，  报表下载结束时间： " + end.getTransdate();
		
		String[] fields = new String[]{"汇卡商户号","商户名称","订单号","系统参考号","交易时间","处理时间","交易金额（单位/元）","业务类型","清算周期"};
		List<Object[]> source = new ArrayList<Object[]>();		
		// 组装数据
		for (BdCallorder item:freezeList) {			
			source.add(new Object[]{
					item.getWpmerchno(), 
					item.getMerchname(),
					item.getOrderno(),
					item.getSysno(),
					DateHelp.numberToDate(item.getTransdate() + item.getTranstime().substring(4)),
					item.getProcdate()==null?"":item.getProcdate(),
					item.getTransmoney(),
					item.getCallflag(),
					item.getPeriod()});
		}
		
		ByteArrayOutputStream bos = rt.createGeneralTemplet(title, descrip, fields, source);
		return bos.toByteArray();
	}
	
	/**
	 * 查询风控传统POS解冻报表
	 * @param start
	 * @param end
	 * @return
	 * @throws Exception
	 */
	public List<BdCallorder> findCallorderReport(BdCallorder start, BdCallorder end) throws Exception{
		//1.只下载已审核通过的 
		start.setCheckstate(PASS);
		//2.限制处理日期 // 格式处理
		if(start.getProcdate()!=null && !"".equals(start.getProcdate())){
			start.setProcdate(start.getProcdate() + " 00:00:00");
		}
		if(end.getProcdate()!=null && !"".equals(end.getProcdate())){
			end.setProcdate(end.getProcdate() + " 23:59:59");	
		}
		
		try {
			return callorderService.findList(start, end);
		} catch (Exception e) {
			logger.error("查询风控传统POS解冻报表", e);
			throw e;
		}
	}
	
	/**
	 * 下载风控传统POS解冻报表
	 * @param start
	 * @param end
	 * @return
	 */
	public byte[] downloadCallorderReport(BdCallorder start, BdCallorder end){
		// 查询出调单管理数据
		List<BdCallorder> freezeList = null;
		try {
			freezeList = findCallorderReport(start, end);
		} catch (Exception e) {
			logger.error("",e);
		}
		if(freezeList == null){
			freezeList = new  ArrayList<BdCallorder>();
		}
		
		// 构建报表
		ReportTemplet rt = new ReportTemplet();
		
		String title = "风控传统pos解冻报表";
		String descrip = "条件：共计 " 
							  + freezeList.size() 
							  + " 条，报表下载开始时间： " + start.getProcdate() 
							  + "，  报表下载结束时间： " + end.getProcdate();
		
		String[] fields = new String[]{"汇卡商户号","商户名称","订单号","系统参考号","交易时间","处理时间","交易金额（单位/元）","业务类型","清算周期"};
		List<Object[]> source = new ArrayList<Object[]>();		
		// 组装数据
		for (BdCallorder item:freezeList) {			
			source.add(new Object[]{
					item.getWpmerchno(), 
					item.getMerchname(),
					item.getOrderno(),
					item.getSysno(),
					DateHelp.numberToDate(item.getTransdate() + item.getTranstime().substring(4)),
					item.getProcdate(),
					item.getTransmoney(),
					item.getCallflag(),
					item.getPeriod()
					});
		}
		
		ByteArrayOutputStream bos = rt.createGeneralTemplet(title, descrip, fields, source);
		return bos.toByteArray();
	}
	
	
	
	
}
